//
//  WBNetworkManager.swift
//  tom微博
//
//  Created by tom king on 2017/8/26.
//  Copyright © 2017年 tom king. All rights reserved.
//

import UIKit
import AFNetworking

/// switch / enum 在 OC 中都只是支持整数
/// swift 的枚举支持任意数据类型
enum WBHttpMethod {
    case GET
    case POST
}

/// 网络管理工具
class WBNetworkManager: AFHTTPSessionManager {

    /// 静态区／常量／闭包
    /// 在第一次访问时，执行闭包，并且将结果保存在 shared 常量中
    static let shared = WBNetworkManager()
    
    /// 用户账户的懒加载属性
    lazy var userAccount = WBUserAccount()
    
    // 用户登录标记[计算型属性]
    var userLogin: Bool {
        return userAccount.access_token != nil
       
    }
    /// 专门负责拼接 token 的网络请求方法
    func tokenRequest (method: WBHttpMethod = .GET, URLString: String, parameters: [String: AnyObject]?,
                       completion: @escaping ((json:AnyObject?, isSuccess: Bool)) -> ()) {
        
        // 处理 token 字典
        // 0> 判断 token 是否为 nil 为 nil 直接返回; 执行过程中，一般 token 不会为 nil
        guard let token = userAccount.access_token else {
            //  发送通知，提示用户登录
            print("没有token，需要登录")
            
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: WBUserShouldLoginNotification), object: nil)
            
            completion((json: nil, isSuccess: false))
            
            return
        }
        
        // 1>判断 参数字典 是否存在，如果为 nil，应该新建一个字典
        var parameters = parameters
        if parameters == nil {
            // 实例化字典
            parameters = [String: AnyObject]()
        }
        
        // 2> 设置参数字典,代码在此处字典一定有值
        parameters!["access_token"] = token as AnyObject
        
        // 调用 request 发起真正的网络请求方法
        request(URLString: URLString, parameters: parameters!, completion: completion)
    }
    
    /// 封装 AFN 的 GET ／ POST 请求
    ///
    /// - Parameters:
    ///   - method: GET/POST
    ///   - URLString: URLString
    ///   - parameters: 参数字典
    ///   - completion: 完成回调[json(字典/数组)， 是否成功]
    func request(method: WBHttpMethod = .GET, URLString: String, parameters: [String: AnyObject],
                 completion: @escaping ((json:AnyObject?, isSuccess: Bool)) -> ()) {
        
        // 成功回调
        let success = { (task: URLSessionDataTask, json: Any?) -> () in
            
            completion((json: json as AnyObject, isSuccess: true))
        }
        // 失败回调
        let failure = { (task: URLSessionDataTask?, error: Error) -> () in
            
            // 针对 403 处理用户 token 过期
            if (task?.response as? HTTPURLResponse)?.statusCode == 403 {
                print("token过期了")
                // 发送通知 提示用户再次登录（本方法不知道被谁调用，谁接收到通知，谁处理）
                NotificationCenter.default.post(
                    name: NSNotification.Name(rawValue: WBUserShouldLoginNotification),
                    object: "bad token")
                
            }
            
            print("网络请求失败\(error)")
            completion((json: nil, isSuccess: false))
    
        }

        if method == .GET {
            get(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }else {
            post(URLString, parameters: parameters, progress: nil, success: success, failure: failure)
        }
    }
}
